//Katherine Jamieson, 11139009, kmj098

#include <stdio.h>
#include <assert.h>
#define MAX_SIZE 65535
typedef float Elem;


struct Vector{
	unsigned int size;
	Elem* elements;
};


//Postcond: new vector of size 0 is created
//Return: newly created vector
Vector *alloc_vec(void){
	
	Vector *newVec = new Vector;
	newVec->size = 0;
	
	newVec->elements = new Elem[newVec->size];
  
	return newVec;
}

//Postcond: elements of vec and vec are deallocated and set to NULL
void dealloc_vec(Vector *vec){
	delete[] vec->elements;
	delete vec;
	vec=NULL;
	assert(vec==NULL);
}

//Precond: vec!=null
//	vec->size <= MAX_SIZE
//Postcond: new vector is created with one element greater than vec, 
//	all elements in vec are copied into new vector and newElement is
//	added as the last element
//	vec is deallocated
//Return: new,  extended vector,  return null if vec==null
Vector *extend_vec(Vector *vec,Elem newElement){
	if(vec==NULL){
		//fprintf(stderr,"unable to extend null vector\n");
		return NULL;
	}
	
	if(vec->size == MAX_SIZE){
		//fprintf(stderr,"max size reached, unable to extend vector\n");
		return vec;
	}
		
	
	Vector *newVector;
	newVector=new Vector;
	newVector->size = (vec->size)+1;
	newVector->elements=new Elem[newVector->size];
		
	for(unsigned int i=0;i<vec->size;i++){
		newVector->elements[i]=vec->elements[i];
	}
		

	newVector->elements[vec->size]= newElement;
		
	dealloc_vec(vec);
		
	return newVector;
}

//Precond: vec!=null
//Postcond: print out each element in vec
//Return: false if vec is null,  otherwise return true
bool print_vec(Vector *vec){
	if(vec==NULL){
		return false;
	}

	for(unsigned int i=0;i<vec->size;i++){
		printf("%f ",vec->elements[i]);
	}
	printf("\n");
	return true;
}

//Precond: vec!=null
//Postcond: add length to each element in vec
//Return: if vec==null return null,  else return vec
Vector *scalar_plus(Vector *vec, Elem length){
	if(vec==NULL){
		//fprintf(stderr,"unable to add to a null vector\n");
		return NULL;
	}
		
	for(unsigned int i=0;i<vec->size;i++){
		vec->elements[i]=vec->elements[i]+length;
	}
	
	return vec;
}

//Precond: vec!=null
//Postcond: each element in vec is length less than orirginally
//return: null if vec==null, otherwise return edited vector
Vector *scalar_minus(Vector *vec, Elem length){
	return NULL;
}
  
//Precond: vec!=null
//Postcond: each element in vec has been multiplied by length
//Return: null if vec==null, otherwise return updated vector
Vector *scalar_mult(Vector *vec, Elem length){
	return NULL;
}

//Precond: vec!=null
//Postcond: each element in vec is divided by length
//Return: null if vec==null, otherwise return updated vector
Vector *scalar_div(Vector *vec, Elem length){
	return NULL;
}

//Postcond: element 0 is set to 6, and element 1 is set to -6
//		Function is used for testing purposes
//Return: vec
Vector *setFirstTwoElements(Vector *vec){
		vec->elements[0]=6;
		vec->elements[1]=-6;
		return vec;
}

//Main function used for testing
int main(int, char**){
	#ifdef TESTING
  
	//create new vectors
	Vector* vec = new Vector;
	Vector* nullVec = NULL;
	
	//allocate and check allocation was succesful
	vec = alloc_vec();
  
	assert(vec!=NULL);
	assert(vec->size == 0);
	
	dealloc_vec(vec);
	
	vec=alloc_vec();
	
	//testing for extend_vec
	assert(extend_vec(nullVec,1)==NULL);
  
	vec=extend_vec(vec,2);
	assert(vec->elements[0]==2);
  
	vec=extend_vec(vec,-4);
	assert(vec->elements[0]==2);
	assert(vec->elements[1]==-4);
	
	vec->size=MAX_SIZE;
	vec=extend_vec(vec,2);
	
	vec->size=2;
  
	//testing for print_vec
	assert(true==print_vec(vec));
	assert(false==print_vec(nullVec));
  

	//testing for scalar_plus
	assert(scalar_plus(nullVec,2)==NULL);

	vec=setFirstTwoElements(vec);
	vec=scalar_plus(vec,2);
	assert(vec->elements[0]==8);
	assert(vec->elements[1]==-4);
  
	//testing for scalar_minus
	assert(scalar_minus(nullVec,2)==NULL);

	vec=setFirstTwoElements(vec);
	vec=scalar_minus(vec,2);
		//this is where testing of program will terminate
	assert(vec->elements[0]==4);
	assert(vec->elements[1]==-8);
	
	//testing for scalar_mult
	assert(scalar_mult(nullVec,2)==NULL);

	//vec=setFirstTwoElements(vec);
	vec=scalar_mult(vec,2);
	assert(vec->elements[0]==12);
	assert(vec->elements[1]==-12);
	
	//testing for scalar_div
	assert(scalar_div(nullVec,2)==NULL);

	//vec=setFirstTwoElements(vec);
	vec=scalar_div(vec,2);
	assert(vec->elements[0]==3);
	assert(vec->elements[1]==-3);
	
	#endif
}
